package org.adream.account.controller;

import org.adream.account.dao.RealNameAuthDao;
import org.adream.account.dao.RealNameTmpDao;
import org.adream.account.dao.UserDao;
import org.adream.account.entity.UserEntity;
import org.adream.account.util.Constant;
import org.adream.account.util.FileUtils;
import org.adream.account.util.Utils;
import org.jasig.cas.client.authentication.AttributePrincipal;
import org.jasig.cas.client.validation.Assertion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.cas.authentication.CasAuthenticationToken;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Map;
import java.util.Set;

@RequestMapping("/file/")
@Controller
public class DownloadImageController {

    private final static Logger logger = LoggerFactory.getLogger(DownloadImageController.class);


    @Value("${image.file.path.userpic}")
    private String userPicPath; // 用户图片

    @Value("${image.file.path.syspic}")
    private String sysPicPath; // 系统图片

    @Value("${image.file.path.verifypic}")
    private String verifyPicPath; // 认证图片

    @Value("${image.file.path.helppic}")
    private String helppicPath; // 帮助中心图片

    @Value("${file.path.resumefile}")
    private String resumeFilePath;

    @Value("${file.path.annuSurveyfile}")
    private String annuSurveyFilePath;

    @Value("${file.path.stufffile}")
    private String stuffFilePath;

    @Value("${file.path.createConCopyfile}")
    private String createConCopyFilePath;

    @Value("${file.path.excuteConCopyfile}")
    private String excuteConCopyFilePath;

    @Autowired
    private RealNameAuthDao authDao;

    @Autowired
    private RealNameTmpDao tmpDao;

    @Autowired
    private UserDao userDao;

    /**
     * 浏览图片
     *
     * @param fileName 图片名称
     * @param type     图片类型
     * @param request
     * @param response
     */
    @RequestMapping(value = "viewimg", method = RequestMethod.GET)
    public void viewimg(@RequestParam("fileName") String fileName, @RequestParam("type") Integer type,
                        HttpServletRequest request, HttpServletResponse response) {
        if (StringUtils.isEmpty(fileName) || type == null) {
            logger.warn("图片浏览失败:参数有误:(");
            return;
        }
        String regex = "^[a-zA-Z0-9_-]+(\\.[a-zA-Z]{3,4})$"; // 带后缀
        String regex2 = "^[a-zA-Z0-9_-]+$";
        if (!fileName.matches(regex) && !fileName.matches(regex2)) { //都不满足
            logger.warn("图片浏览失败：参数非法");
            return;
        }

        String file = "";
        if (Constant.ONE == type) {
            //用户图片
            file = userPicPath.endsWith(File.separator + "") ? userPicPath : userPicPath + File.separator;
        } else if (Constant.TWO == type) {
            //系统图片
            file = sysPicPath.endsWith(File.separator + "") ? sysPicPath : sysPicPath + File.separator;
        } else if (Constant.THREE == type) {
            //认证图片
            //有实名管理或认证管理权限或自己可查看认证图片
            Object o = new Object();
            o = request.getUserPrincipal();
            if (o == null || !(o instanceof CasAuthenticationToken)) {
                PrintWriter out = null;
                try {
                    response.setContentType("text/html;charset=UTF-8");
                    out = response.getWriter();
                    out.write("登录信息失效,请重新登录");
                    return;
                } catch (IOException e) {
                    logger.warn("图片浏览失败:" + e.getMessage());
                } finally {
                    if (out != null) {
                        out.close();
                    }
                }
            }
            //获取登录信息
            CasAuthenticationToken token = (CasAuthenticationToken) o;
            Assertion assertion = token.getAssertion();
            AttributePrincipal principal = assertion.getPrincipal();
            Map<String, Object> map = principal.getAttributes();
            if (StringUtils.isEmpty(map.get("uid"))) {
                PrintWriter out = null;
                try {
                    response.setContentType("text/html;charset=UTF-8");
                    out = response.getWriter();
                    out.write("登录信息失效,请重新登录");
                    return;
                } catch (IOException e) {
                    logger.warn("图片浏览失败:" + e.getMessage());
                } finally {
                    if (out != null) {
                        out.close();
                    }
                }
            }
            //获取全部权限
            String resIdStr = (String) map.get("resIds");
            //权限为空 || (既没有实名认证管理权限又没有身份认证管理权限)
            if (StringUtils.isEmpty(resIdStr) ||
                    (resIdStr.indexOf(Constant.REALNAME_MANAGER_RES_ID) == -1 &&
                            resIdStr.indexOf(Constant.VERIFY_MANAGER_RES_ID) == -1 &&
                            resIdStr.indexOf(Constant.REALNAME_SHOW_RES_ID) == -1
                    )) {
                String uid = (String) map.get("uid");
                //通过图片文件查询是否是本人
                Set<String> authUids = authDao.queryUidsByCrePicAndDr(fileName, Constant.ONE);
                if (Utils.isEmptyCollection(authUids) || !authUids.contains(uid)) {
                    Set<String> tmpUids = tmpDao.queryUidsByCrePicAndDr(fileName, Constant.ONE);
                    if (Utils.isEmptyCollection(tmpUids) || !tmpUids.contains(uid)) {
                        PrintWriter out = null;
                        try {
                            response.setContentType("text/html;charset=UTF-8");
                            out = response.getWriter();
                            out.write("图片浏览失败:权限不足");
                            return;
                        } catch (IOException e) {
                            logger.warn("图片浏览失败:" + e.getMessage());
                        } finally {
                            if (out != null) {
                                out.close();
                            }
                        }
                    }
                }
            }
            file = verifyPicPath.endsWith(File.separator + "") ? verifyPicPath : verifyPicPath + File.separator;
        } else if (Constant.FOUR == type) {
            //帮助中心图片
            file = helppicPath.endsWith(File.separator + "") ? helppicPath : helppicPath + File.separator;
        }
        file = file + fileName;
        FileUtils.readFile(file, response);
    }

    /**
     * file/headimg/uid_height*width uid_分辨率访问头像  无头像时使用默认头像
     * 若无分辨率时,不进行压缩
     *
     * @param uid
     * @param response
     */
    @RequestMapping(value = "headimg/{uidHeightWidth}")
    public void viewimg(@PathVariable("uidHeightWidth") String uidHeightWidth, HttpServletRequest request, HttpServletResponse response) {
        if (StringUtils.isEmpty(uidHeightWidth)) {
            logger.warn("图片浏览失败:参数有误:(");
            return;
        }
        String uid;
        String file = "";
        int height = 0;
        int width = 0;
        if (uidHeightWidth.indexOf("_") != -1) {
            uid = uidHeightWidth.split("_")[0];
            String heightWidth = uidHeightWidth.split("_")[1];
            //heightWidth格式不为 height*width
            if (heightWidth.indexOf("*") == -1 || heightWidth.split("\\*").length != Constant.TWO
                    || !Utils.isInteger(heightWidth.split("\\*")[0]) || !Utils.isInteger(heightWidth.split("\\*")[1])) {
                logger.warn("图片浏览失败:参数有误:(");
                return;
            }
            height = Integer.parseInt(heightWidth.split("\\*")[0]);
            width = Integer.parseInt(heightWidth.split("\\*")[1]);
        } else {
            uid = uidHeightWidth;
        }
        UserEntity user = userDao.queryUserByUid(uid);
        //判断获取后面带文件分隔符的用户图片路径
        String path = userPicPath.endsWith(File.separator + "") ? userPicPath : userPicPath + File.separator;
        //用户不存在或用户无头像或用户头像不存在 使用默认头像
        if (user == null || StringUtils.isEmpty(user.getHeadimgurl()) || !new File(path + user.getHeadimgurl()).exists()) {
            file = path + "moren.png";
        } else {
            file = path + user.getHeadimgurl();
        }
        FileUtils.readFile(file, response, width, height);
//        FileInputStream fis = null;
//        OutputStream os = null;
//        try {
//            fis = new FileInputStream(file);
//            os = response.getOutputStream();
//            int count = 0;
//            byte[] buffer = new byte[1024 * 8];
//            while ((count = fis.read(buffer)) != -1) {
//                os.write(buffer, 0, count);
//                os.flush();
//            }
//        } catch (Exception e) {
//            logger.info("图片浏览失败:)");
//        } finally {
//            try {
//                if (fis != null) {
//                    fis.close();
//                }
//                if (os != null) {
//                    os.close();
//                }
//                //若生成了图片缩略图
//                if (!uid.equals(uidHeightWidth) && height != 0 && width != 0) {
//                    //删除图片缩略图
//                    new File(file).delete();
//                }
//            } catch (Exception e2) {
//                logger.info("图片浏览失败:)");
//            }
        //       }
    }

    /**
     * 下载图片
     *
     * @param request
     * @param response
     * @param fileName 文件名称
     * @param type     文件类型
     */
    @RequestMapping(value = "download")
    public void download(HttpServletRequest request, HttpServletResponse response,
                         @RequestParam("fileName") String fileName, @RequestParam("type") Integer type) {
        // 获取服务器文件
        String file = "";
        if (Constant.ONE == type) {
            file = resumeFilePath.endsWith(File.separator) ? resumeFilePath : resumeFilePath + File.separator;
        } else if (Constant.TWO == type) {
            file = annuSurveyFilePath.endsWith(File.separator) ? annuSurveyFilePath
                    : annuSurveyFilePath + File.separator;
        } else if (Constant.THREE == type) {
            file = stuffFilePath.endsWith(File.separator) ? stuffFilePath : stuffFilePath + File.separator;
        } else if (Constant.FOUR == type) {
            file = createConCopyFilePath.endsWith(File.separator) ? createConCopyFilePath
                    : createConCopyFilePath + File.separator;
        } else if (Constant.FIVE == type) {
            file = excuteConCopyFilePath.equals(File.separator) ? excuteConCopyFilePath
                    : excuteConCopyFilePath + File.separator;
        }
        file = file + fileName;
        FileUtils.downFile(file, response);
    }
}